package jmind.core.serialize;


import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoPool;
import org.objenesis.strategy.StdInstantiatorStrategy;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * description:
 *
 * @author weibo.xie
 * @date : create in 5:38 下午 2021/5/13
 */
public class KryoSerializer  implements Serializer {

    private static final KryoPool kryoPool = newKryoPool();

    private static KryoPool newKryoPool() {
        return new KryoPool.Builder(() -> {
            final Kryo kryo = new Kryo();
            kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(
                    new StdInstantiatorStrategy()));
            kryo.setReferences(false);
            kryo.setRegistrationRequired(false);
            return kryo;
        }).softReferences().build();
    }

    @Override
    public byte[] serialize(Object object) throws IOException {
        Kryo kryo = kryoPool.borrow();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        Output output = new Output(os);
        kryo.writeClassAndObject(output,object);
        byte[] bytes = output.toBytes();
        output.close();
        os.close();
        kryoPool.release(kryo);
        return bytes;
    }

    @Override
    public Object deserialize(byte[] bytes) throws IOException {
        Kryo kryo = kryoPool.borrow();
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        Input input = new Input(bis);
        Object object = kryo.readClassAndObject(input);
        input.close();
        bis.close();
        kryoPool.release(kryo);
        return object;
    }


}